﻿using System;
using System.Collections.Generic;
using System.Configuration;
using System.Linq;
using System.Text;
using Mindfor.Web.Data;
using System.Collections.Specialized;

namespace Mindfor.Web.Config
{
	/// <summary>
	/// Represents mindfor.cms config section.
	/// </summary>
	public class CmsConfig : ConfigurationSection
	{
		static CmsConfig s_default;

		/// <summary>
		/// Gets CMS configuration from web.config file.
		/// </summary>
		public static CmsConfig Default
		{
			get
			{
				if (s_default == null)
					s_default = LoadFromDefaultConfigFile();
				return s_default;
			}
		}
		/// <summary>
		/// Loades CMS configuration from web.config file.
		/// </summary>
		/// <returns>CMS configuration from web.config.</returns>
		private static CmsConfig LoadFromDefaultConfigFile()
		{
			try
			{
				CmsConfig config = (CmsConfig)ConfigurationManager.GetSection("mindfor.webmp");
				if (config == null)
					throw new CmsConfigException("Can not find <mindfor.webmp> section.");
				if (config.User.AuthenticateBy == AuthenticationType.Email && !config.User.IsEmailRequired)
					throw new CmsConfigException("<user> section can not have \"authenticateBy=Email\" true and \"isEmailRequired=false\".");
				return config;
			}
			catch (ConfigurationException ex)
			{
				throw new CmsConfigException("An error occured while loading configuration section <mindfor.webmp>.", ex);
			}
		}

		/// <summary>
		/// Gets data provider configuration section.
		/// </summary>
		[ConfigurationProperty("dataProvider", IsRequired = true)]
		public DataProviderElement DataProvider
		{
			get { return (DataProviderElement)this["dataProvider"]; }
			private set { this["dataProvider"] = value; }
		}

		/// <summary>
		/// Gets user configuration section.
		/// </summary>
		[ConfigurationProperty("user")]
		public UserElement User
		{
			get { return (UserElement)this["user"]; }
			private set { this["user"] = value; }
		}

		/// <summary>
		/// Gets mail configuration section.
		/// </summary>
		[ConfigurationProperty("mail")]
		public MailElement Mail
		{
			get { return (MailElement)this["mail"]; }
			private set { this["mail"] = value; }
		}

		/// <summary>
		/// Gets or sets site unique application id used to authorize at mindfor server.
		/// </summary>
		[ConfigurationProperty("applicationId")]
		public Guid? ApplicationId
		{
			get { return (Guid?)this["applicationId"]; }
			set { this["applicationId"] = value; }
		}

		/// <summary>
		/// Gets or sets default site language url name.
		/// </summary>
		[ConfigurationProperty("defaultLanguage")]
		public string DefaultLanguage
		{
			get { return (string)this["defaultLanguage"]; }
			set { this["defaultLanguage"] = value; }
		}

		/// <summary>
		/// Gets or sets whether user-friendly error message is enabled.
		/// </summary>
		[ConfigurationProperty("enableErrorMessage", DefaultValue=true)]
		public bool EnableErrorMessage
		{
			get { return (bool)this["enableErrorMessage"]; }
			set { this["enableErrorMessage"] = value; }
		}

		/// <summary>
		/// Gets or sets whether to enable deflate and gzip output compression for dynamic content (pages).
		/// </summary>
		[ConfigurationProperty("enableDynamicCompression", DefaultValue=false)]
		public bool EnableDynamicCompression
		{
			get { return (bool)this["enableDynamicCompression"]; }
			set { this["enableDynamicCompression"] = value; }
		}

		/// <summary>
		/// Gets or sets whether to enable deflate and gzip output compression for static content (css and javascript).
		/// </summary>
		[ConfigurationProperty("enableStaticCompression", DefaultValue=false)]
		public bool EnableStaticCompression
		{
			get { return (bool)this["enableStaticCompression"]; }
			set { this["enableStaticCompression"] = value; }
		}

		/// <summary>
		/// Gets or sets error message design layout filename.
		/// System will look for file in /Views/Shared.
		/// File must contain "[ErrorMessage]" w/o brackets.
		/// </summary>
		[ConfigurationProperty("errorDesignLayoutName", DefaultValue = "Error.html")]
		public string ErrorDesignLayoutName 
		{
			get { return (string)this["errorDesignLayoutName"]; }
			set { this["errorDesignLayoutName"] = value; }
		}

		/// <summary>
		/// Gets connection strings collection.
		/// </summary>
		public ConnectionStringSettingsCollection ConnectionStrings
		{
			get { return ConfigurationManager.ConnectionStrings; }
		}

		/// <summary>
		/// Gets application settings collection.
		/// </summary>
		public NameValueCollection AppSettings
		{
			get { return ConfigurationManager.AppSettings; }
		}
	}
}
